#include "hnswlib_index.h"
HNSWLibIndex::HNSWLibIndex(int dim,int num_data,IndexFactory::MetricType metric,int M,int ef_construction):maxElements(num_data){
    bool normalize=false;
    if(metric==IndexFactory::MetricType::L2){
        space=new hnswlib::L2Space(dim);
    }else{
        throw std::runtime_error("not support metric");
    }
    index=new hnswlib::HierarchicalNSW<float>(space,num_data,M,ef_construction,normalize);
}

void HNSWLibIndex::insert_vectors(const std::vector<float>& data,uint64_t label){
    index->addPoint(data.data(),label);
}

std::pair<std::vector<long>,std::vector<float>> HNSWLibIndex::search_vectors(const std::vector<float>&query,int k,int ef_search){
    index->setEf(ef_search);
    auto result=index->searchKnn(query.data(),k);

    std::vector<long> indeces(k);
    std::vector<float> distances(k);
    for(int j=0;j<k;++j){
        auto it=result.top();
        indeces[j]=it.second;
        distances[j]=it.first;
        result.pop();
    }
    return {indeces,distances};
}

//保存
void HNSWLibIndex::saveIndex(const std::string& file_path){
    index->saveIndex(file_path);
}
//加载
void HNSWLibIndex::loadIndex(const std::string& file_path){
    std::ifstream input_file(file_path);
    if(input_file.good()){
        input_file.close();
        index->loadIndex(file_path,space,maxElements);
    }else{
        GlobalLogger->warn("File not found {},skip loading hnsw index",file_path);
    }
}